#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time      :2022/5/20 10:38
# @Author    :cjw
import logging
import time
from typing import List, Optional

import pytest
import allure

from web_wework.page.main_page import MainPage
from web_wework.util.generate_data import GenerateData

m_page: Optional[MainPage] = None  # 微信首页
gd: GenerateData = GenerateData()  # 数据生成器


@pytest.fixture()
def main_page():
	"""
	每次用例执行，都需要创建一个新的driver驱动，所以都需要创建一个主页的实例
	:return:
	"""
	global m_page
	logging.info('启动浏览器，进入首页...')
	m_page = MainPage()
	yield m_page, gd
	logging.info('关闭浏览器...\n')
	m_page.quit()


@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
	"""
	获取每个用例状态的钩子函数，进行失败用例截图

	具体执行过程如下：
	1、先执行when='setup'，返回setup 的执行结果
	2、然后执行when='call'，返回call 的执行结果
	3、最后执行when='teardown'，返回teardown 的执行结果

	运行用例的过程会经历三个阶段:setup-call-teardown,
	每个阶段都会返回的 Result 对象和 TestReport 对象，以及对象属性。
	:param item: 测试用例
	:param call: 用例步骤
	:return:
	"""
	outcome = yield  # 获取钩子方法的调用结果
	report = outcome.get_result()  # 从调用结果中获取测试报告

	# 只获取用例运行时失败的结果，即when='call'
	if report.when == 'call' and report.failed:
		now_time = time.strftime('%Y_%m_%d_%H_%M_%S')
		# 用例失败，添加allure报告截图
		if hasattr(m_page.driver, 'get_screenshot_as_png'):
			with allure.step('添加失败截图'):
				logging.info(f'添加失败截图')
				allure.attach(m_page.driver.get_screenshot_as_png(), f'失败截图_{now_time}',
				              allure.attachment_type.PNG)


def pytest_collection_modifyitems(
		session: "Session", config: "Config", items: List["Item"]
) -> None:
	"""
	修改测试用例名称编码，执行顺序
	:param session: pytest session 对象
	:param config: 配置信息对象
	:param items: 收集到的所有测试用例对象列表，name：用例名称，nodeid：用例路径
	:return:
	"""
	for item in items:
		# 修改用例名称和路径的编码
		# nodeid是用例对象的属性方法，真正改变的是用例对象的_nodeid属性
		item.name = item.name.encode('utf-8').decode('unicode-escape')
		item._nodeid = item.nodeid.encode('utf-8').decode('unicode-escape')


@pytest.fixture(scope="session", autouse=True)
def manage_logs(request):
	"""设置日志文件的文件名称"""
	now = time.strftime("%Y-%m-%d %H-%M-%S")
	log_name = 'log/' + now + '.log'

	request.config.pluginmanager.get_plugin("logging-plugin").set_log_path(log_name)
